

class MetaClass(type):
    def __new__(cls, name, bases, attrs):
        if 'properties' in attrs:
            for prop in attrs['properties']:
                if isinstance(prop, str):
                    print(f"MetaClass {name}: {prop}")
                    attrs[prop] = lambda self: getattr(self.Instance, prop) if hasattr(self.Instance, prop) else None
        return super().__new__(cls, name, bases, attrs)


class Object(metaclass=MetaClass):
    def __init__(self, instance):
        assert(instance is not None)
        self.Instance = instance

    @staticmethod
    def constant(name):
        from win32com.client import constants
        dictionary = constants.__dicts__[0]
        if name in dictionary.keys():
            return dictionary[name]
        else:
            return None


class Set(Object):
    def __init__(self, instance, elementType):
        super().__init__(instance)
        self.ElementType = elementType

    @property
    def Count(self):
        return self.Instance.Count

    @property
    def First(self):
        return self.Instance.First

    @property
    def Last(self):
        return self.ElementType(self.Instance.Last)

    def Item(self, index):
        assert(index >= 1)
        return self.ElementType(self.Instance.Item(index))

    def __item__(self, index):
        return self.Item(index + 1)

    def __iter__(self):
        for index in range(self.Count):
            item = self.Item(index + 1)
            assert(isinstance(item, self.ElementType))
            yield item

    def saveobj(self):
        data = []
        for item in self:
            data.append(item)
        return data
